#include "util.h"
#include "parser.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include "termInput.h"

void flushEscapeSequence(char escape_sequence[]) {
	escape_sequence[0] = 0;
	escape_sequence[1] = 0;
	escape_sequence[2] = 0;
}

int specialChar(char escape_sequence[]) {
	if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 65) {
		flushEscapeSequence(escape_sequence);
		return UP;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 66) {
		flushEscapeSequence(escape_sequence);
		return DOWN;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 67) {
		flushEscapeSequence(escape_sequence);
		return RIGHT_KEY;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 68) {
		flushEscapeSequence(escape_sequence);
		return LEFT_KEY;
	} else if(escape_sequence[0] == 12 || escape_sequence[1] == 12 || escape_sequence[2] == 12) {
		flushEscapeSequence(escape_sequence);
		return CTRL_L;
	}

	return -1;

}

char * readLine(listHistory hist) {
	char escape_sequence[3] = {0,0,0};                      /* Vetor que armazena sequencias de escape */
	char c;
	int escapeIndex = 0;                                    /* Inidice do vetor de sequencias de escape */
	int specialCharCode;
	nodeHistory nodeHist=NULL;
	char *current_dir = getcwd(NULL,0);                     /* Pega o diretório de trabalho atual */
	struct winsize ws;                                      /* Guarda informações sobre o terminal */
	termInput term = createTermInput(10,10);  /* termInput contém todas as informações necessárias para manipular a entrada do terminal */

	/* Pegando propriedades do terminal, estamos interessados no número de colunas */
	ioctl(1, TIOCGWINSZ, &ws);

	printf("%s :: ",current_dir);

	while((c = getchar()) != '\n') {
		escape_sequence[escapeIndex++] = c;
		if(escape_sequence[0] != 27) {
			escapeIndex = 0;
			flushEscapeSequence(escape_sequence);
		}

		if(escapeIndex > 2) {
			escapeIndex = 0;
		}
		specialCharCode = specialChar(escape_sequence);
		if(specialCharCode != -1) {
			if(specialCharCode == UP) {
				if(nodeHist == NULL) {
                                	nodeHist = hist->head;
                                 	if(nodeHist != NULL) {
						replaceBuffer(term,nodeHist->string);
                                 	}
                         	} else if(nodeHist->next != NULL) {
                                 	nodeHist = nodeHist->next;
					replaceBuffer(term,nodeHist->string);
                         	}

			} else if(specialCharCode == DOWN) {
				if(nodeHist != NULL) {
                                 	if(nodeHist->prev != NULL) {
                                         	nodeHist = nodeHist->prev;
						replaceBuffer(term,nodeHist->string);
                                 	}
                         	}
			} else if(specialCharCode == LEFT_KEY) {
				moveCursor(term,LEFT);
			} else if(specialCharCode == RIGHT_KEY) {
				moveCursor(term,RIGHT);
			}
		} else if(escape_sequence[0] != 27) {
			if(c >= 32 && c <= 126) {
				addChar(term,c);
			} else if(c == 13) {
				printf("%c",c);
				break;
			} else if(c == 127) {
				removeChar(term);
			} else if(c == 9) { /* TAB */
				int n;
				char **commands = parser(term->buffer,&n,' ');
				directoryList dirList; /* Guarda a lista de todas as entradas de um dado diretório */
				searchIndex results;   /* Guarda o indice dos resultados de uma pesquisa por determinado pedaço de string */
				if(n > 1) { /* Se há mais de um comando, a pesquisa por arquivos é feita no diretório atual */
					dirList = getDirFileList(current_dir);					
					results = search(dirList,commands[n-1]);
					if(results->size == 1) {
						commands[n-1] = dirList->list[results->v[0]];
						replaceBuffer(term,concat(commands,n));
					}
				} else {

				}
			
			} else if(c == 12) {
				char *r = (char *)malloc(6*sizeof(char));
				strcpy(r,"clear");
				return r;
			}
		}
	printf("\r%s :: %s",current_dir,term->buffer);
	printSpaces(ws.ws_col - strlen(current_dir) - strlen(term->buffer) - 4);
	posCursor(term);
	//printf("   ASCII: %d   ",c);
	}

	escapeIndex = 0;
	return term->buffer;
}
 
char * concat(char **s, int n) {
	int i;
	char *r;
	int size=0;

	for(i=0;i<n;i++) {
		size += strlen(s[i]);
	}
	size += 2*n - 1;

	r = (char *)malloc(size*sizeof(char));
	r[0] = '\0';

	for(i=0;i<n;i++) {
		if(i == n-1) {
			strcat(r,s[i]);
		} else {
			strcat(r,s[i]);
			strcat(r," ");
		}
	}

	return r;

}

char * getLastWord(char *s) {
	char *r;

	int size = strlen(s);
	int i,j,k,count=0;

	i = size-1;
	if(s[i] == ' ') {
		while(s[i] == ' ' && i >= 0) {
			size--;
			i--;
		}
	}

	if(i == 0) {
		return NULL;
	}

	for(i=size-1;i>=0;i--) {
		if(s[i] == ' ') {
			j = i+1;
			break;
		}
		count++;
	}

	if(i == -1) {
		j = 0;
	}

	r = (char *)malloc((count+1)*sizeof(char));


	for(i=j,k=0;i<size;i++) {
		r[k++] = s[i];
	}
	r[k] = '\0';

	return r;
}

void printSpaces(int n) {
        int i;

        for(i = 0;i<n;i++) {
                printf(" ");
        }
        for(i = 0;i<n;i++) {
                printf("\b");
        }
}

